/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package pdf;

import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
import com.openbrew.openbrewrf.Administration;
import com.openbrew.openbrewrf.Employee;
import com.openbrew.openbrewrf.POLines;
import com.openbrew.openbrewrf.PurchaseOrder;
import com.openbrew.openbrewrf.Vendors;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import javax.imageio.ImageIO;
import view.SimplePurchaseOrderView;

/**
 *
 * @author chapmand
 */
public class POPDFCreator {
    private SimplePurchaseOrderView simplePurchaseOrderView = null;
    private String leftOver = null;
    private Administration admin = null;
    private int linespace = 10;
        
    private final int borderSize = 50;
    private static final String HELVETICA = "helvetica";
    private static final Font TITLE_FONT = new Font(HELVETICA, Font.BOLD, 12);
    private static final Font TEXT_FONT = new Font(HELVETICA, Font.PLAIN, 8);
    private final DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
    
    public void createPDF(OutputStream outputStream, PurchaseOrder purchaseOrder, SimplePurchaseOrderView simplePurchaseOrderView, final Administration admin){
        try{
            Document document = new Document(PageSize.A4, borderSize, borderSize, borderSize, borderSize);
            //PdfWriter.getInstance(document, outputStream);   
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            document.open();
            PdfContentByte canvas = writer.getDirectContent();
            // Create the Graphics2D object.
            Graphics2D g2d = canvas.createGraphics(PageSize.A4.getWidth(), PageSize.A4.getHeight());
            
            //Create page 1 image
            makePOView(g2d, purchaseOrder, simplePurchaseOrderView, admin);
            
            g2d.dispose();
            
            if(leftOver != null){
                appendPDFPage(document, canvas, leftOver, purchaseOrder);
            }
            
            Paragraph paragraph = new Paragraph();
            paragraph.add(new Chunk(""));
            document.add(paragraph);
            
            document.close();
        }catch(Exception ex){
            
        }
    }
    
    private void appendPDFPage(final Document document, final PdfContentByte canvas, final String sales, final PurchaseOrder purchaseOrder){
        document.newPage();
        Graphics2D g2d2 = canvas.createGraphics(PageSize.A4.getWidth(), PageSize.A4.getHeight());
        
        //Create Next Page View.
        makePONView(g2d2, purchaseOrder, sales);

        g2d2.dispose();
        if(leftOver != null){
            appendPDFPage(document, canvas, leftOver, purchaseOrder);
        }
    }
    
    private void makePONView(final Graphics2D g2d2, PurchaseOrder purchaseOrder, final String sales){
        g2d2.setPaint(Color.BLACK);
        
        //Draw Graphics to PDF.
        addGraphics(g2d2);

        //Draw Header to PDF.
        addHeaderInfo(g2d2, purchaseOrder);

        //Draw Invoice Data to PDF.
        addVendorPOData(g2d2, purchaseOrder, sales);

        //Draw Footer Data to PDF.
        addFooterData(g2d2);
    }
    
    private void makePOView(final Graphics2D g2d, PurchaseOrder purchaseOrder, SimplePurchaseOrderView simplePurchaseOrderView, Administration admin){
        setView(simplePurchaseOrderView, admin);
        g2d.setPaint(Color.BLACK);
        //Draw Graphics to PDF.
        addGraphics(g2d);

        //Draw Header to PDF.
        addHeaderInfo(g2d, purchaseOrder);

        //Draw Invoice Data to PDF.
        addVendorPOData(g2d, purchaseOrder, simplePurchaseOrderView.getOverview());

        //Draw Footer Data to PDF.
        addFooterData(g2d);
    }
    
    public void setView(SimplePurchaseOrderView simplePurchaseOrderView, final Administration admin){
        this.simplePurchaseOrderView = simplePurchaseOrderView;
        this.admin = admin;
    }
                
    private Vendors getFirstVendor(final List<POLines> polines){
        if(polines.isEmpty()){
            return null;
        }
        for(final POLines poline : polines) {
            Vendors vend = poline.getPolpn().getStockVendID();
            return vend;
        }
        return null;
    }
    
    private void addGraphics(final Graphics2D g2d){
        // Print Logos (Logo.JPG and BLogo.JPG
        BufferedImage image = null;
        BufferedImage image2 = null;
        if(admin.getHeaderImg()!=null){
            try{
                InputStream in = new ByteArrayInputStream(admin.getHeaderImg());
                BufferedImage hdrbi = ImageIO.read(in);  
                image = hdrbi;
            } catch (IOException ex){

            }
        }
        if(admin.getFooterImg()!=null){
            try{
                InputStream in = new ByteArrayInputStream(admin.getFooterImg());
                BufferedImage hdrbi = ImageIO.read(in);  
                image2 = hdrbi;
            } catch (IOException ex){

            }
        }
        // Render the image on the sheet
        g2d.drawImage(image, borderSize, borderSize, 66, 100, null);
        final double imgy = (PageSize.A4.getHeight() - 66 - borderSize);
        final double imgx = (PageSize.A4.getWidth() - 66 - borderSize);
        // Render second image on sheet.
        g2d.drawImage(image2, (int) imgx, (int) imgy, 66, 66, null);
    }

    private void addHeaderInfo(final Graphics2D g2d, final PurchaseOrder purchaseOrder){
        // ---Section 1 (Header)
        // Print the header
        final String titleText = admin.getBreweryName();
        g2d.setFont(TITLE_FONT);

        // Comput the right alignment on the page.
        FontMetrics fontMetrics = g2d.getFontMetrics();
        final double titleX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(titleText));
        final double titleY = 14 + borderSize;
        g2d.drawString(titleText, (int) titleX, (int) titleY);

        // Print the address.
        final String addressText0 = admin.getBreweryStreetAddress() + " "
                + admin.getBreweryCity() + ", " + admin.getBreweryState() + " "
                + admin.getBreweryZipCode();
        final String addressText1 = admin.getBreweryPhoneNumber();
        final String addressText2 = admin.getBreweryEmail();
        final int addressY = 14 + borderSize;
        g2d.setFont(TEXT_FONT);

        // Compute the right alignment for the address info.
        fontMetrics = g2d.getFontMetrics();
        double addressX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(addressText0));
        g2d.drawString(addressText0, (int) addressX, (addressY + (linespace * 1)));
        addressX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(addressText1));
        g2d.drawString(addressText1, (int) addressX, (addressY + (linespace * 2)));
        addressX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(addressText2));
        g2d.drawString(addressText2, (int) addressX, (addressY + (linespace * 3)));

        // Get Purchase Order information.
        Vendors vend = getFirstVendor(purchaseOrder.getPOLinesCollection());
        final String invoiceNumber = Integer.toString(purchaseOrder.getPoid());

        // Print Invoice Data:
        final String invoiceNumberString = "PO NUMBER: " + invoiceNumber;
        final String invoiceDateString = "PO DATE: " + dateFormat.format(purchaseOrder.getPODate());
        g2d.setFont(TEXT_FONT);

        // Compute the right alignment for the invoice info.
        fontMetrics = g2d.getFontMetrics();
        double textX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(invoiceNumberString));
        final int iY = (addressY + (linespace * 5));
        g2d.drawString(invoiceNumberString, (int) textX, (iY + (linespace * 1)));
        textX = (PageSize.A4.getWidth()- borderSize) - (fontMetrics.stringWidth(invoiceDateString));
        g2d.drawString(invoiceDateString, (int) textX, (iY + (linespace * 2)));
    }
    
    private void addFooterData(final Graphics2D g2d){
        // -- Section 3 (Footer)
        Employee billingEmp = admin.getBillingEmp();
        // Print Contact Info.
        final String gContact = "Contact Info:";
        final String gBilling = "AP: " + billingEmp.getEmpFirstName() + " " 
                + billingEmp.getEmpLastName() + " - " + billingEmp.getEmpPhone();
        final String gBillingAddr = billingEmp.getEmpEmail();

        // Compute and display contact info.
        double textX = 0 + borderSize;
        final double textY = (PageSize.A4.getHeight() - 66 - borderSize);
        linespace = 10;

        g2d.drawString(gContact, (int) textX, (int) textY);
        g2d.drawString(gBilling, (int) textX, ((int) textY + (linespace * 2)));
        g2d.drawString(gBillingAddr, (int) textX, ((int) textY + (linespace * 3)));
    }
    
    private void addVendorPOData(final Graphics2D g2d, final PurchaseOrder purchaseOrder, final String sales){
        FontMetrics fontMetrics = g2d.getFontMetrics();
        Vendors vend = getFirstVendor(purchaseOrder.getPOLinesCollection());
        // -- Section 2 (Vendor data and invoice)
        // Print Customer Data:
        final String custTo = "TO:";
        final String custName = vend.getVName();
        final String custAddr = vend.getVAddr();
        final String custCSZ = vend.getVCity() + ", " + vend.getVState() + " " + vend.getVZip();
        final String custPhone = vend.getVPhone();

        // Calculate Customer Position.
        final int cY = 180 + borderSize;
        double textX = (fontMetrics.stringWidth(custTo) + 6) + borderSize;
        g2d.drawString(custTo, borderSize, (cY + (linespace * 1)));
        g2d.drawString(custName, (int) textX, (cY + (linespace * 1)));
        g2d.drawString(custAddr, (int) textX, (cY + (linespace * 2)));
        g2d.drawString(custCSZ, (int) textX, (cY + (linespace * 3)));
        g2d.drawString(custPhone, (int) textX, (cY + (linespace * 4)));

        // -- Section 2 Part B List Invoice.
        final int itemFieldXPosition = 0 + borderSize;
        final int qtyFieldXPosition = 300 + borderSize;
        final int productFieldXPosition = 350 + borderSize;
        final int costFieldXPosition = 400 + borderSize;
        int tY = cY + (linespace * 6);

        // Print out headers of file.
        final String headerItem = "Item:";
        final String headerQty = "Qty:";
        final String headerProduct = "Cost:";
        final String headerCost = "Sub Total:";

        g2d.drawString(headerItem, itemFieldXPosition, tY);
        g2d.drawString(headerQty, qtyFieldXPosition, tY);
        g2d.drawString(headerProduct, productFieldXPosition, tY);
        g2d.drawString(headerCost, (int) costFieldXPosition, tY);

        tY += linespace;

        String[] salesArray = sales.split("\n");
        leftOver = null;
        int count = 0;
        for (final String element : salesArray) {
                count++;
                if(count >=40){
                    if(leftOver == null){
                        leftOver = element + "\n";
                    } else {
                        leftOver += element + "\n";
                    }
                } else {
                    final String[] totals = element.split(",");

                    g2d.drawString(totals[0], itemFieldXPosition, tY);
                    g2d.drawString(totals[1], qtyFieldXPosition, tY);
                    g2d.drawString(totals[2], productFieldXPosition, tY);
                    g2d.drawString(totals[3], (int) costFieldXPosition, tY);

                    tY += linespace;
                }
        }

        tY += linespace;

        if(leftOver == null){
            final String totalCost = simplePurchaseOrderView.getCost();
            final String ttl = "Total:";

            final double ttlX = costFieldXPosition - fontMetrics.stringWidth(ttl) - 5;

            g2d.drawString(totalCost, (int) costFieldXPosition, tY);
            g2d.drawString(ttl, (int) ttlX, tY);

            tY += linespace;
        }
    }
    
}
